package com.ruoyi.web.controller.api;


import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.WxLoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.WxTokenService;
import com.ruoyi.task.domain.TaskExamine;
import com.ruoyi.task.domain.TaskManagement;
import com.ruoyi.task.domain.TaskUser;
import com.ruoyi.task.domain.TaskWithdraw;
import com.ruoyi.task.domain.VO.SubmitTaskVO;
import com.ruoyi.task.domain.VO.WithdrawalVO;
import com.ruoyi.task.service.ITaskExamineService;
import com.ruoyi.task.service.ITaskManagementService;
import com.ruoyi.task.service.ITaskUserService;
import com.ruoyi.task.service.ITaskWithdrawService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Api(tags = "我的相关接口")
@RestController
@RequestMapping("/api/myUser")
@Slf4j
public class MyUserController extends BaseController {


    @Autowired
    private ITaskExamineService taskExamineService;

    @Autowired
    private WxTokenService wxTokenService;

    @Autowired
    private ITaskUserService iTaskUserService;

    @Autowired
    private ITaskWithdrawService iTaskWithdrawService;

    @Autowired
    private RedisDistributedLock redisDistributedLock;

    @ApiOperation("我的任务")
    @GetMapping("getTask")
    public TableDataInfo getTask(HttpServletRequest request,TaskExamine taskExamine){
        WxLoginUser wxLoginUser = wxTokenService.getWxUser(request);
        startPage();
        List<TaskExamine> list = taskExamineService.getTaskExamine(wxLoginUser.getUserId());
        return getDataTable(list);
    }

    @ApiOperation("我的团队")
    @GetMapping("getTeam")
    public TableDataInfo getTeam(HttpServletRequest request,TaskExamine taskExamine){
        WxLoginUser wxLoginUser = wxTokenService.getWxUser(request);
        startPage();
        List<TaskUser> list = iTaskUserService.selectTaskUserByReferenceId(wxLoginUser.getUserId());
        return getDataTable(list);
    }

   /* @ApiOperation("提现")
    @PostMapping("withdrawal")
    public AjaxResult submitTask(HttpServletRequest request ,@Validated @RequestBody WithdrawalVO submitTaskVO ){
        WxLoginUser wxLoginUser = wxTokenService.getWxUser(request);
        TaskUser taskUser = iTaskUserService.selectTaskUserById(wxLoginUser.getUserId());
        if (taskUser == null){
            return error("用户不存在");
        }
        if (taskUser.getWxAccount() == null || taskUser.getWxAccount().equals("")
        && taskUser.getPaymentCode() == null || taskUser.getPaymentCode().equals("")){
            return error("请先绑定微信账户以及上传收款码，才能完成提现操作!");
        }
        if (submitTaskVO.getAmount().compareTo(taskUser.getFreezeDeposits()) > 0) {
            return AjaxResult.error("提现金额不能大于实际金额");
        }

        // 获取提现金额和冷冻金额
        BigDecimal withdrawAmount = submitTaskVO.getAmount();
        BigDecimal freezeDeposits = taskUser.getFreezeDeposits();
        BigDecimal remainingAmount = freezeDeposits.subtract(withdrawAmount);
        taskUser.setFreezeDeposits(remainingAmount);
         int updateCount =  iTaskUserService.updateTaskUser(taskUser);
        if (updateCount == 0) {
            // 更新失败，可能是并发冲突
            return error("提现失败，请稍后重试");
        }
        TaskWithdraw taskWithdraw = new TaskWithdraw();
        taskWithdraw.setUserId(wxLoginUser.getUserId());
        taskWithdraw.setAmount(submitTaskVO.getAmount());
        taskWithdraw.setCurrentBalance(freezeDeposits);
        taskWithdraw.setSuccessfulBalance(remainingAmount);
        log.info("提现成功，剩余金额：{}", remainingAmount);
        log.info("提现成功，剩余金额：{}", taskWithdraw);
        return success(iTaskWithdrawService.insertTaskWithdraw(taskWithdraw));
    }*/

    @ApiOperation("提现")
    @PostMapping("withdrawal")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult submitTask(HttpServletRequest request, @Validated @RequestBody WithdrawalVO submitTaskVO) {
        WxLoginUser wxLoginUser = wxTokenService.getWxUser(request);
        Long userId = wxLoginUser.getUserId();
        BigDecimal withdrawAmount = submitTaskVO.getAmount();

        // 参数校验
        if (withdrawAmount == null || withdrawAmount.compareTo(BigDecimal.ZERO) <= 0) {
            return error("提现金额必须大于0");
        }

        // 生成唯一请求ID和锁key
        String requestId = UUID.randomUUID().toString();
        String lockKey = "withdrawal:user:" + userId;

        log.info("用户{}开始提现，金额：{}，请求ID：{}", userId, withdrawAmount, requestId);

        // 尝试获取锁，最多等待5秒
        boolean lockAcquired = false;
        long startTime = System.currentTimeMillis();
        long maxWaitTime = 2000; // 最多等待5秒

        while (System.currentTimeMillis() - startTime < maxWaitTime && !lockAcquired) {
            lockAcquired = redisDistributedLock.tryLock(lockKey, requestId, 30); // 锁30秒

            if (!lockAcquired) {
                try {
                    Thread.sleep(100); // 等待100ms后重试
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    log.error("等待锁被中断，用户ID：{}", userId);
                    return error("系统繁忙，请稍后重试");
                }
            }
        }

        if (!lockAcquired) {
            log.warn("用户{}获取提现锁失败，超时", userId);
            return error("系统繁忙，请稍后重试");
        }

        log.info("用户{}成功获取提现锁", userId);

        try {
            // 重新查询用户信息（确保数据最新）
            TaskUser taskUser = iTaskUserService.selectTaskUserById(userId);
            if (taskUser == null) {
                return error("用户不存在");
            }

            // 验证用户绑定信息
            if (StringUtils.isEmpty(taskUser.getWxAccount()) || StringUtils.isEmpty(taskUser.getPaymentCode())) {
                return error("请先绑定微信账户以及上传收款码，才能完成提现操作!");
            }

            // 检查余额
            BigDecimal currentBalance = taskUser.getFreezeDeposits();
            if (currentBalance == null) {
                currentBalance = BigDecimal.ZERO;
            }

            if (withdrawAmount.compareTo(currentBalance) > 0) {
                return error("提现金额不能大于实际金额，当前余额：" + currentBalance);
            }

            // 计算剩余金额
            BigDecimal remainingAmount = currentBalance.subtract(withdrawAmount);

            // 更新用户余额
            taskUser.setFreezeDeposits(remainingAmount);
            int updateCount = iTaskUserService.updateFreezeDepositsByUserId(taskUser);
            if (updateCount == 0) {
                log.error("更新用户余额失败，用户ID：{}，原余额：{}，提现金额：{}",
                        userId, currentBalance, withdrawAmount);
                return error("提现失败，请稍后重试");
            }

            // 创建提现记录
            TaskWithdraw taskWithdraw = new TaskWithdraw();
            taskWithdraw.setUserId(userId);
            taskWithdraw.setAmount(withdrawAmount);
            taskWithdraw.setCurrentBalance(currentBalance);
            taskWithdraw.setSuccessfulBalance(remainingAmount);
            taskWithdraw.setCreateTime(new Date());

            int insertResult = iTaskWithdrawService.insertTaskWithdraw(taskWithdraw);
            if (insertResult > 0) {
                log.info("用户{}提现成功，提现金额：{}，余额从{}变为{}",
                        userId, withdrawAmount, currentBalance, remainingAmount);
                return success("提现申请已提交");
            } else {
                log.error("创建提现记录失败，用户ID：{}", userId);
                throw new RuntimeException("创建提现记录失败");
            }

        } catch (Exception e) {
            log.error("提现操作异常，用户ID：{}，提现金额：{}", userId, withdrawAmount, e);
            return error("提现失败，请稍后重试");
        } finally {
            // 释放锁
            boolean released = redisDistributedLock.releaseLock(lockKey, requestId);
            if (released) {
                log.info("用户{}提现锁释放成功", userId);
            } else {
                log.warn("用户{}提现锁释放失败，lockKey: {}, requestId: {}", userId, lockKey, requestId);
            }
        }
    }

}
